//! @author Adam Emil Skoog
//! @date   2012-01-05

#include "Level.h"
#include "Drawable.h"
#include "Mehdi.h"

namespace mehdi
 {
	Level::Level()
	:
	cameraMovementEnabled(true) {}

	void Level::update()
	 {
		for (unsigned i(0); i < objects.size(); ++ i)
		 {
			Body *const body1(dynamic_cast<Body *>(objects[i]));

			if (body1)
			 {
				body1->updatePhysics();

				if (body1->isReceptiveToGravity())
					body1->inAir = true;

				for (unsigned j(0); j < bodies.size(); ++ j)
				 {
					if (bodies[j] != objects[i])
					 {
						Body *const body2(bodies[j]);

						for (unsigned k(0); k < body1->getCollisionMasks().size(); ++ k)
						 {
							for (unsigned l(0); l < body2->getCollisionMasks().size(); ++ l)
							 {
								if (body1->getCollisionMasks()[k]->collidesWith(body2->getCollisionMasks()[l],
									body1->position(),body2->position()))
								 {
									if (body1->isReceptiveToCollision() && body2->isReceptiveToCollision())
									 {
										if (body1->isReceptiveToGravity() && body1->position().y < body2->position().y)
											body1->land(body2);

										if (body2->isReceptiveToGravity() && body2->position().y < body1->position().y)
											body2->land(body1);
									 }

									body1->onCollision(body2);
									body2->onCollision(body1);
								 }
							 }
						 }
					 }
				 }
			 }

			objects[i]->update();

			if (dynamic_cast<Drawable *>(objects[i]))
				dynamic_cast<Drawable *>(objects[i])->draw();
		 }

		Mehdi::drawHUD();
	 }

	void Level::copyMehdi(Mehdi *const mehdi,Level *const oldLevel)
	 {
		objects.push_back(mehdi);
		bodies.push_back(mehdi);
		oldLevel->eraseMehdi();
	 }

	void Level::eraseMehdi()
	 {
		for (unsigned i(0); i < objects.size(); ++ i)
		 {
			if (dynamic_cast<Mehdi *>(objects[i]))
			 {
				objects.erase(objects.begin() + i);
				break;
			 }
		 }

		for (unsigned i(0); i < bodies.size(); ++ i)
		 {
			if (dynamic_cast<Mehdi *>(bodies[i]))
			 {
				bodies.erase(bodies.begin() + i);
				break;
			 }
		 }
	 }

	Level &Level::setCameraMovementEnabled(const bool &enable)
	 {
		cameraMovementEnabled = enable;
		return *this;
	 }

	const bool &Level::cameraMovementIsEnabled() const
	 {
		return cameraMovementEnabled;
	 }

	Level::~Level()
	 {
		for (unsigned i(0); i < objects.size(); ++ i)
			delete objects[i];

		objects.clear();
	 }
 }
